#include "vrrpd_api.h"
#include "pal.h"

static int
_my_send_advert (struct interface *ifp, int sock, struct stream *s, int size,
              u_int8_t  af_type)
{
	struct pal_sockaddr_in4			sin;
	struct pal_in4_addr 			addr;
	struct connected              	*ifc;
  	int                           	nbytes;
  	int                           	found = 0;
  	result_t                      	ret = 0;
  	struct prefix                 	*p;

	if(af_type == AF_INET)
		{
			/* Set IP */
			pal_mem_set(&addr, 0, sizeof(struct pal_in4_addr));
			/* Make destination address */
			pal_mem_set(&sin, 0, sizeof(struct pal_sockaddr_in4);
			sin.sin_addr.s_addr = pal_hton32 (VRRP_MCAST_ADDR);
      		sin.sin_family = AF_INET;

			/* Get connected interface */
			for(ifc = ifp->ifc_ipv4; ifc; ifc = ifc->next)
				{
					p = ifc->address;
				if (! CHECK_FLAG (ifc->flags, NSM_IFA_VIRTUAL))
             		{
              			 /* Set the socket address */
               			addr = p->u.prefix4;
						found = 1;
               			break;
             		}
				} // end get connected

				if(!found) {
					return VRRP_FAILURE;
				}

			/* Set interface as multicast */
			ret = pal_sock_set_ipv4_multicast_if(sock, addr, ifp->ifindex);

			/* Send the advertisement message */
			nbytes = pal_sock_sendto(sock, s->data, size, 0, (struct pal_sockaddr*) &sin, sizeof (struct pal_sockaddr_in4));
			if (nbytes != size)
				{
					return VRRP_FAILURE;
				}
		}
	return VRRP_OK;
}



int my_vrrp_send_advert_v2(VRRP_SESSION * sess,u_int8_t prio)
{
	struct stream *s = NULL;
	struct vrrpd_advt_info *my_vi = NULL;
	struct nsm_if *nsm_if;
	u_int16_t advt_int = 0;

	nsm_if = sess->ifp->info;
	if(sess->af_type == AF_INET)
		{
			/* allocate space for advt */
			s = stream_new(MY_VRRP_ADVT_SIZE);
			/* Fill in the advertisement message prior to filling in the stream */
			/* This is necessary to perform the checksum calculation */

			/* Put Version and Type */
			stream_putc(s, (MY_VRRP_VERSION << 4) | MY_VRRP_ADVT_TYPE);
			/* Put VRID */
			stream_putc(s, sess->vrid);
			/* Put Priority */
			stream_putc(s, prio);
			/* Put Number of IP address */
			stream_putc(s, sess->num_ip_addrs);
			/* Put Authentication-type */
			stream_putc(s, VRRP_AUTH_NONE);
			/* Put advertisement interval */
			stream_putc(s, sess->adv_int);
			/* Put checksum (init = 0) */
			stream_putw(s, 0);
			/* Put Virutal IP address */
			stream_put_in_addr(s, &sess->vip_v4);
			/* Clear authentication data field */
			stream_putl(s, 0);
			stream_putl(s, 0);
			
			/* Calculate checksum and update */
			my_vi = (struct vrrpd_advt_info*)STREAM_DATA(s);
			my_vi->cksum = in_checksum((u_int16_t *) my_vi,MY_VRRP_ADVT_SIZE);

			/* Call the appropriate IP interaction routine to transmit the message */
			/* Call the function to send ADVERTISEMENT message */
			if(_my_send_advert(sess->ifp, sess->vrrp->sock, s, MY_VRRP_ADVT_SIZE, sess->af_type) != VRRP_OK) {
					// Error in sending ADVERTISEMENT
					stream_free(s);
					return VRRP_FAILURE;
				}
			// Success in sending ADVERTISEMENT
			stream_free(s);
			return VRRP_OK;
		}
	return VRRP_FAILURE;
}